package com.vogtec.fota.mqtt;

import lombok.extern.slf4j.Slf4j;
import org.eclipse.paho.client.mqttv3.*;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * Created by TieYan on 2017/5/22.
 */
@Configuration
@Slf4j
public class MqttConfiguration {
	@Bean
	public BikeEmqttClient bikeEmqttClient(@Value("${mqtt.broker}") String broker,
										   @Value("${mqtt.clientid}") String clientId,
										   @Value("${mqtt.username}") String username,
										   @Value("${mqtt.password}") String password) throws MqttException {
		BikeEmqttClient bikeEmqttClient = new BikeEmqttClient();
		bikeEmqttClient.setMqttClient(getMqttClient(broker, clientId, username, password));
		return bikeEmqttClient;
	}

	@Bean
	public MqttCallback getMqttCallback() {
		return new EmqttCallBack();
	}

	public MqttAsyncClient getMqttClient(String broker, String clientId, String username, String password) throws MqttException {
		MqttAsyncClient mqttClient;
		mqttClient = new MqttAsyncClient(broker, clientId);

		mqttClient.setCallback(getMqttCallback());

		MqttConnectOptions connOpt = mqttConnectOptions(username, password);
		mqttClient.connect(connOpt, null, new IMqttActionListener() {
			public void onSuccess(IMqttToken asyncActionToken) {
				log.info("connected broker successfully...");
				try {
					subscribeServiceTopics(mqttClient);
				} catch (MqttException e) {
					e.printStackTrace();
					log.error("", e);
					System.exit(0);
				}
			}

			public void onFailure(IMqttToken asyncActionToken, Throwable exception) {
				log.error("connected broker failed...exit!!!");
				System.exit(0);
			}
		});
		return mqttClient;
	}

	@Value("${mqtt.address}")
	private String node;

	private void subscribeServiceTopics(MqttAsyncClient mqttClient) throws MqttException {
		mqttClient.subscribe("vogtec/gx/fota/ack",1,null,new SubscribeListener("vogtec/gx/fota/ack"));
		mqttClient.subscribe("vogtec/gx/version/info",1,null,new SubscribeListener("vogtec/gx/version/info"));
		mqttClient.subscribe("$SYS/brokers/" + node + "/clients/+/connected", 1,
				null,new SubscribeListener("$SYS/brokers/${mqtt.address}/clients/+/connected"));

//		mqttClient.subscribe(Topics.LOCK, 1/*TODO Config*/, null, new SubscribeListener(Topics.LOCK));
//		mqttClient.subscribe(Topics.UNLOCK_ACK, 1/*TODO Config*/, null, new SubscribeListener(Topics.UNLOCK_ACK));
//		mqttClient.subscribe(Topics.LOCK_ADD, 1, null, new SubscribeListener(Topics.LOCK_ADD));
	}

	class SubscribeListener implements IMqttActionListener {
		String topic;

		public SubscribeListener(String topic) {
			this.topic = topic;
		}

		@Override
		public void onSuccess(IMqttToken asyncActionToken) {
			log.info("subscribe " + topic + " topic successfully...");
		}

		@Override
		public void onFailure(IMqttToken asyncActionToken, Throwable exception) {
			log.error("subscribe " + topic + " topic failed...exit!!!");
			System.exit(0);
		}
	}

	private MqttConnectOptions mqttConnectOptions(String username, String password) {
		MqttConnectOptions connOpt = new MqttConnectOptions();
		connOpt.setCleanSession(true);
		connOpt.setUserName(username);
		connOpt.setKeepAliveInterval(60);
		connOpt.setConnectionTimeout(60);
		connOpt.setAutomaticReconnect(true);
		connOpt.setPassword(password.toCharArray());
		return connOpt;
	}
}
